/*globals jQuery */
// Global namespace
var TJ = TJ || {};

// Modules namespace
TJ.Modules = {};

TJ.RegisteredModules = [];

TJ.Config = {
    'ModulePath' : '/js/',
    'PageContextCssClass' : '.page'
};

// Check if Firebug is available
if (!(window.console && window.console.firebug)) {
    console = {
        info : function () {
        },
        log : function () {
        },
        assert : function () {
        }
    };
}

/**
 * OOP inherit
 * @param p {function) Function to inherit from
 * @return {function} Instance of new function with inherited properties of param p
 */
TJ.inherit = function (p) {
    function F() {}
    F.prototype = p;
    return new F();
};

TJ.integrate_module = function (NewFunction, function_name) {
    NewFunction.prototype = TJ.inherit(TJ.Module.prototype);
    NewFunction.prototype.constructor = NewFunction;
    TJ.Modules[function_name] = new NewFunction();
    return true;
};

(function ($) {

    function Init() {
        var $ctx = null,
            retrieve_module_name_from_css_class = null,
            load_module_script = null,
            number_of_modules = 0,
            register_module = null;

        $ctx = $(TJ.Config.PageContextCssClass);

        if ($ctx.length !== 1) {
            throw new Error('No .page context defined');
        }

        retrieve_module_name_from_css_class = function (css_class) {
            if (css_class.indexOf('mod ') !== -1) {
                var module_name = css_class.match(/mod[A-Za-z]+/);
                if (module_name !== null) {
                    return module_name[0];
                } else {
                    return false;
                }
            } else {
                return false;
            }
        };

        console.assert(retrieve_module_name_from_css_class('mod modMyMod') !== false);
        console.assert(retrieve_module_name_from_css_class('od modMyMod') === false);
        console.assert(retrieve_module_name_from_css_class('mod mdMyMod') === false);

        load_module_script = function (module_name, callback) {
            $.getScript(TJ.Config.ModulePath + 'TJ.Module.' + module_name + '.js', function (data, e) {
                callback(data, e);
            });    
        };

        register_module = function ($ctx) {
            var module_name = '',
                module_css_class = '';

            module_css_class = retrieve_module_name_from_css_class($ctx.attr('class'));

            module_name = module_css_class.split('mod')[1];

            load_module_script(module_name, function () {
                
                if (TJ.Modules[module_name] && $.isFunction(TJ.Modules[module_name].init)) {
                    
                    
                    TJ.Modules[module_name].init($ctx, {

                        'beforeload' : function () {
                            //console.info('initializing ' + module_name);
                        },
                        'afterload' : function () {
                            console.info('loaded ' + module_name);
                        }
                    });
                }
            });

            return module_name;
        };

        $(TJ).bind('modulesRegistered', function () {
            console.info(TJ.RegisteredModules);    
        });

        number_of_modules = $('.mod', $ctx).length;

        $('.mod', $ctx).each(function (i) {
            TJ.RegisteredModules.push(register_module($(this)));

            if (number_of_modules === (i + 1)) {
                $(TJ).trigger('modulesRegistered');
            }
        });     
    }

    TJ.Init = Init;

    return true;
}(jQuery));

jQuery(function () {
    // Start this party
    TJ.Init();
});